package com.apes.framework.plugin.form.parser.element;

import com.apes.framework.api.SpringManager;
import com.apes.framework.plugin.form.parser.node.FormNodeParser;
import com.apes.framework.plugin.filereader.xml.ApesElement;
import com.apes.framework.plugin.filereader.xml.ApesElementParser;
import com.apes.framework.plugin.filereader.xml.SimpleApesElement;
import com.apes.framework.util.LogicalUtil;
import lombok.Data;
import org.dom4j.Attribute;
import org.dom4j.tree.DefaultAttribute;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 功能：按钮栏解析
 *
 * @author xul
 * @create 2018-04-20 17:10
 */
@Component
public class ButtonbarElementParser extends AbstractElementParser {

    /**
     * 可解析的元素列表
     **/
    private final String[] elementNames = {"buttonbar"};

    /**
     * 功能：可解析节点域
     */
    @Override
    public String getDomain() {
        return FormNodeParser.domain;
    }

    /**
     * 功能：可解析的元素列表
     */
    @Override
    public String[] getNames() {
        return elementNames;
    }


    /**
     * 功能：解析子节点
     *
     * @param node
     * @param elements
     */
    @Override
    protected void parseNestedElements(Map node, Collection<ApesElement> elements) {
        elements = addDefaultButton(elements);
        node.put("buttonbar", elements.stream()
                .map(new Function<ApesElement, Object>() {
                    @Override
                    public Object apply(ApesElement apesElement) {
                        return apesElement.parse();
                    }
                }).collect(Collectors.toList()));
    }

    private List<ApesElement> addDefaultButton(Collection<ApesElement> elements) {
        /**添加默认按钮**/
        List<ApesElement> buttons = new ArrayList<>();
        buttons.add(createButtonElement(new Button("action_wf_submit", "OA提交", "one", "{'hide': [('states', '!=', 'submit')]}, {'disabled': ['|', ('form.valid', '=', false) , ('valid', '=', false)]}", "{'states':'new'}", "primary", true, "")));
        buttons.add(createButtonElement(new Button("action_wf_resolve", "转签", "one", "{'hide': [('states', '!=', 'submit')]}, {'disabled': ['|', ('form.valid', '=', false) , ('valid', '=', false)]}", "{'states':'new'}", "default", true, "Z")));
        buttons.add(createButtonElement(new Button("action_wf_apostille", "加签", "one", "{'hide': [('states', '!=', 'submit')]}, {'disabled': ['|', ('form.valid', '=', false) , ('valid', '=', false)]}", "{'states':'new'}", "default", true, "J")));
        buttons.add(createButtonElement(new Button("action_wf_countersign", "会签", "one", "{'hide': [('states', '!=', 'submit')]}, {'disabled': ['|', ('form.valid', '=', false) , ('valid', '=', false)]}", "{'states':'new'}", "default", true, "H")));
//        buttons.add(createButtonElement(new Button("action_wf_reject", "驳回", "one", "{'hide': [('states', '!=', 'submit')]}, {'disabled': ['|', ('form.valid', '=', false) , ('valid', '=', false)]}", "{'states':'new'}", "default", true, "B")));

        if(!elements.isEmpty()) {
            buttons.add(createButtonElement(new Button("action_new", "创建", "two", "{'hide': [('states', '!=', 'new')]}", "{'states':'submit'}", "primary", false, "")));
            buttons.add(createButtonElement(new Button("action_submit", "保存", "one", "{'hide': [('states', '!=', 'submit')]}", "{'states':'new'}", "primary", false, "")));
            buttons.add(createButtonElement(new Button("action_cancel", "放弃", "one", "{'hide': [('states', '!=', 'submit')]}", "{'states':'new'}", "default", false, "")));
            buttons.add(createButtonElement(new Button("action_search", "查找", "one", "{'hide': [('states', '!=', 'new')]}", "{'states':'new'}", "default", false, "")));
        }
        /**对按钮位置重新排序**/
        List<ApesElement> result = new ArrayList<>();
        buttons.forEach(v -> {
            if (v.getAttribute("name").equals("action_cancel")) {
                result.addAll(elements.stream().filter(element -> LogicalUtil.notIn(element.getAttribute("name"), "action_new", "action_submit", "action_cancel", "action_search")).collect(Collectors.toList()));
            }
            if (elements.stream().filter(element -> element.getAttribute("name").equals(v.getAttribute("name"))).count() == 0) {
                result.add(v);
            } else {
                result.addAll(elements.stream().filter(element -> element.getAttribute("name").equals(v.getAttribute("name"))).collect(Collectors.toList()));
            }
        });
        return result;
    }

    private ApesElement createButtonElement(Button button) {
        List<Attribute> attributes = new ArrayList<>();
        Attribute attribute = new DefaultAttribute("name", button.getName());
        attributes.add(attribute);
        attribute = new DefaultAttribute("string", button.getString());
        attributes.add(attribute);
        attribute = new DefaultAttribute("step", button.getStep());
        attributes.add(attribute);
        attribute = new DefaultAttribute("attrs", button.getAttrs());
        attributes.add(attribute);
        attribute = new DefaultAttribute("context", button.getContext());
        attributes.add(attribute);
        attribute = new DefaultAttribute("style", button.getStyle());
        attributes.add(attribute);
        attribute = new DefaultAttribute("wf", String.valueOf(button.isWf()));
        attributes.add(attribute);
        attribute = new DefaultAttribute("auth", String.valueOf(button.getAuth()));
        attributes.add(attribute);
        return SpringManager.getBean(FormNodeParser.class).parse("button", new ArrayList<>(), attributes, "", null);
    }

    @Data
    class Button {
        private String name;
        private String string;
        private String step;
        private String attrs;
        private String context;
        private String style;
        private boolean wf = false;
        private String auth;

        public Button(String name, String string, String step, String attrs, String context, String style, boolean wf, String auth) {
            this.name = name;
            this.string = string;
            this.step = step;
            this.attrs = attrs;
            this.context = context;
            this.style = style;
            this.wf = wf;
            this.auth = auth;
        }

    }
}
